"use strict";
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (Object.prototype.hasOwnProperty.call(b, p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        if (typeof b !== "function" && b !== null)
            throw new TypeError("Class extends value " + String(b) + " is not a constructor or null");
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.BaseEnvironment = void 0;
/*
 * @Author: hongbin
 * @Date: 2022-12-10 11:12:36
 * @LastEditors: hongbin
 * @LastEditTime: 2023-09-30 10:21:27
 * @Description:初始化环境
 */
var THREE = require("three");
var OrbitControls_1 = require("three/examples/jsm/controls/OrbitControls");
// import { OrbitControls as MyOrbitControls } from "../addons/OrbitControls";
var RoomEnvironment_js_1 = require("three/examples/jsm/environments/RoomEnvironment.js");
var ModelLoad_1 = require("./ModelLoad");
var Sky_1 = require("three/examples/jsm/objects/Sky");
/**
 * 初始化 scene camera renderer lights
 */
var BaseEnvironment = /** @class */ (function (_super) {
    __extends(BaseEnvironment, _super);
    function BaseEnvironment(params) {
        var _this = _super.call(this) || this;
        _this.camera = new THREE.PerspectiveCamera();
        _this.lights = [];
        _this.scene = new THREE.Scene();
        /**
         * 初始化环境
         */
        // initEnv(
        //     parameters?: IProps,
        //     canvasLayout?: ICanvasLayout
        // ) {
        // this.initRenderer(parameters, canvasLayout);
        // this.initScene();
        // }
        _this.setCamera = function (params) {
            Object.assign(_this.camera, params);
        };
        /**
         * 保证this指向
         */
        _this.selfResetLayout = function () { return _this.resetLayout.call(_this); };
        _this.canvas = params.canvas;
        _this.initRenderer(params);
        _this.pmremGenerator = new THREE.PMREMGenerator(_this.renderer);
        _this.initScene();
        return _this;
    }
    /**
     * 添加灯光
     */
    // protected initLights() {
    //     const hemisphereLight = new THREE.HemisphereLight(
    //         0xdddddd,
    //         0xffffff,
    //         0.8
    //     );
    //     hemisphereLight.position.set(0, -2, 110);
    //     // 平行光 默认从上往下照 position =  Object3D.DEFAULT_UP
    //     const directionalLight = new THREE.DirectionalLight(0xffffff, 0.45);
    //     this.lights = [hemisphereLight, directionalLight];
    //     this.scene.add(...this.lights);
    // }
    BaseEnvironment.prototype.initLights = function () {
        var _a;
        {
            var hemisphereLight = new THREE.HemisphereLight(0xffffff, 0xeeeeee, 0.4);
            this.lights.push(hemisphereLight);
        }
        {
            var light = new THREE.DirectionalLight(0xffffff, 0.5);
            this.lights.push(light);
            light.position.set(0, 1, -1);
        }
        {
            var light = new THREE.DirectionalLight(0xffffff, 0.5);
            this.lights.push(light);
            light.position.set(-1, 0, 0);
        }
        {
            var light = new THREE.DirectionalLight(0xffffff, 0.5);
            this.lights.push(light);
            light.position.set(1, 1, 1);
        }
        (_a = this.scene).add.apply(_a, this.lights);
        //保留初始亮度
        this.lights.forEach(function (l) {
            l.userData.intensity = l.intensity;
        });
    };
    BaseEnvironment.prototype.setLightIntensity = function (intensity) {
        this.lights.forEach(function (l) {
            l.intensity = l.userData.intensity * intensity;
        });
    };
    BaseEnvironment.prototype.initScene = function () {
        // this.initLights();
        this.orbitControls();
        // this.useRoomEnvironment();
    };
    BaseEnvironment.prototype.useSkyEnvironment = function (env) {
        var _a;
        var sky = new Sky_1.Sky();
        this.scene.add(sky);
        sky.scale.setScalar(10000);
        this.scene.environment && (this.scene.environment.needsUpdate = true);
        var skyUniforms = sky.material.uniforms;
        skyUniforms["turbidity"].value = 1;
        skyUniforms["rayleigh"].value = 1;
        skyUniforms["mieCoefficient"].value = 0.005;
        skyUniforms["mieDirectionalG"].value = 0.8;
        var sun = new THREE.Vector3();
        sun.x = 0.1;
        sun.y = 0;
        sun.z = -1;
        sky.material.uniforms["sunPosition"].value.copy(sun);
        if (env) {
            (_a = this.scene.environment) === null || _a === void 0 ? void 0 : _a.dispose();
            this.scene.environment = this.pmremGenerator.fromScene(sky).texture;
        }
        return sky.material;
    };
    BaseEnvironment.prototype.useRoomEnvironment = function () {
        var _a;
        (_a = this.scene.environment) === null || _a === void 0 ? void 0 : _a.dispose();
        this.scene.environment = this.pmremGenerator.fromScene(new RoomEnvironment_js_1.RoomEnvironment(), 0.04).texture;
    };
    /**
     * 设置背景 十六进制颜色
     */
    BaseEnvironment.prototype.setBackground = function (color) {
        this.scene.background = new THREE.Color(color);
    };
    /**
     * 添加辅助坐标
     */
    BaseEnvironment.prototype.addAxis = function (length) {
        var axes = new THREE.AxesHelper(length || 1000);
        this.scene.add(axes);
    };
    /**
     * 添加控制器
     */
    BaseEnvironment.prototype.orbitControls = function () {
        var _this = this;
        // const controls = new OrbitControls(
        //     this.camera,
        //     this.renderer.domElement
        // );
        var controls = new OrbitControls_1.OrbitControls(this.camera, this.renderer.domElement);
        // controls.minDistance = -100;
        this.controls = controls;
        controls.addEventListener("change", function () {
            _this.render();
        });
    };
    /**
     * 控制镜头缩放等级
     */
    BaseEnvironment.prototype.zoom = function (min, max) {
        this.controls.minZoom = min;
        this.controls.maxZoom = max;
    };
    /**
     * 镜头移动距离限制
     */
    BaseEnvironment.prototype.distance = function (min, max) {
        this.controls.minDistance = min;
        this.controls.maxDistance = max;
    };
    /**
     * 镜头垂直方向旋转角度 默认 0-180 即 angle(0,Math.PI)
     */
    BaseEnvironment.prototype.angle = function (min, max) {
        this.controls.minPolarAngle = min;
        this.controls.maxPolarAngle = max;
    };
    /**
     * 手动指定尺寸
     */
    BaseEnvironment.prototype.appointSize = function (width, height) {
        this.camera.aspect = width / height;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(width, height);
        this.render();
    };
    /**
     * 根据新的父元素尺寸 重置相关参数
     */
    BaseEnvironment.prototype.resetLayout = function () {
        var _a = this.computeCanvasSize(), w = _a[0], h = _a[1];
        this.camera.aspect = w / h;
        this.camera.updateProjectionMatrix();
        this.renderer.setSize(w, h);
        this.render();
    };
    /**
     * 添加resize监听
     */
    BaseEnvironment.prototype.listenResize = function () {
        window.addEventListener("resize", this.selfResetLayout);
    };
    BaseEnvironment.prototype.removeResizeListen = function () {
        window.removeEventListener("resize", this.selfResetLayout);
    };
    /**
     * 清除scene中的物体
     */
    BaseEnvironment.prototype.clearChildren = function (obj) {
        while (obj.children.length > 0) {
            this.clearChildren(obj.children[0]);
            obj.remove(obj.children[0]);
        }
        if (obj.geometry)
            obj.geometry.dispose();
        if (obj.material) {
            if (Array.isArray(obj.material)) {
                obj.material.forEach(function (m) { return m.dispose(); });
            }
            else
                obj.material.dispose();
        }
    };
    /**
     * 清除画布中的元素 用于热更新后显示新画布元素
     */
    BaseEnvironment.prototype.clearScene = function () {
        var _a;
        this.clearChildren(this.scene);
        // 清除背景纹理
        (_a = this.scene.environment) === null || _a === void 0 ? void 0 : _a.dispose();
    };
    /**
     * 渲染画布
     */
    BaseEnvironment.prototype.render = function () {
        this.renderer.render(this.scene, this.camera);
    };
    /**
     * 计算画布的宽高 由其其父元素决定 填充父元素
     */
    BaseEnvironment.prototype.computeCanvasSize = function () {
        var parent = this.renderer.domElement.parentElement;
        if (!parent)
            throw new Error("未获取canvas父元素");
        var offsetWidth = parent.offsetWidth, offsetHeight = parent.offsetHeight;
        return [offsetWidth, offsetHeight];
    };
    BaseEnvironment.prototype.initRenderer = function (parameters) {
        this.renderer = new THREE.WebGLRenderer(parameters);
        this.renderer.outputColorSpace = THREE.SRGBColorSpace
        // 像素比 分辨率
        // this.renderer.setPixelRatio(layout.pixelRatio);
        var windowPix = window.devicePixelRatio;
        var pixelRatio = (parameters === null || parameters === void 0 ? void 0 : parameters.limitPixelRatio)
            ? windowPix
            : Math.min(windowPix, 2);
        this.renderer.setPixelRatio(pixelRatio);
        this.resetLayout();
        return this.renderer;
    };
    /**
     * 将背景设置成透明
     */
    BaseEnvironment.prototype.transparentBackGround = function () {
        //背景透明 主要是第二个参数 alpha
        this.renderer.setClearColor(0x000000, 0);
    };
    /**
     * @description: 设置背景颜色透明度
     * @param {number} alpha 0-透明 1-不透明
     */
    BaseEnvironment.prototype.setBackGroundAlpha = function (alpha) {
        this.renderer.setClearColor(0x000000, alpha);
    };
    return BaseEnvironment;
}(ModelLoad_1.ModelsLoad));
exports.BaseEnvironment = BaseEnvironment;
